<?php

namespace Aincrid\MySwoole\Server\Event;

use Swoole\Server;

class TcpEvent
{
    /**
     * 1、启动后在主进程（master）的主线程回调此函数
     * 2、SWOOLE_BASE 模式下没有 master 进程，因此不存在 onStart 事件，请不要在 BASE 模式中使用 onStart 回调函数。
     * 3、onStart 回调中，仅允许 echo、打印 Log、修改进程名称。不得执行其他操作 (不能调用 server 相关函数等操作，因为服务尚未就绪)。onWorkerStart 和 onStart 回调是在不同进程中并行执行的，不存在先后顺序。
     * 可以在 onStart 回调中，将 $server->master_pid 和 $server->manager_pid 的值保存到一个文件中。这样可以编写脚本，向这两个 PID 发送信号来实现关闭和重启的操作。
     * onStart 事件在 Master 进程的主线程中被调用。
     * @param Server $server
     * @return void
     */
    public static function onStart(Server $server)
    {

    }

    /**
     * 1、此事件在 Server 正常结束前发生
     * 2、Swoole 版本 >= v4.8.0 可用。在此事件中可以使用协程 API。
     * @param Server $server
     * @return void
     */
    public static function onBeforeShutdown(Server $server)
    {

    }

    /**
     * 1、此事件在 Server 正常结束时发生
     * 2、在此之前 Swoole\Server 已进行了如下操作
     *    已关闭所有 Reactor 线程、HeartbeatCheck 线程、UdpRecv 线程
     *    已关闭所有 Worker 进程、 Task 进程、User 进程
     *    已 close 所有 TCP/UDP/UnixSocket 监听端口
     *    已关闭主 Reactor
     * 3、强制kill进程不会回调onShutdown，需要使用kill -15 来发送SIGTERM 信号到主进程才能按照正常流程终止
     * 4、在命令行使用Ctrl+C 中断程序会立即停止，底层不会回调onShutdown
     * 5、请勿在onShutdown中调用任何异步或协程相关API，触发onShutdown时底层已销毁所有事件循环设施
     * @param Server $server
     * @return void
     */
    public static function onShutdown(Server $server)
    {

    }


    /**
     * 1、此事件在 Worker 进程 / Task 进程 启动时发生，这里创建的对象可以在进程生命周期内使用。
     * 2、可以通过 $server->taskworker 属性来判断当前是 Worker 进程还是 Task 进程
     * 3、设置了 worker_num 和 task_worker_num 超过 1 时，每个进程都会触发一次 onWorkerStart 事件，可通过判断 $worker_id 区分不同的工作进程
     * 4、由 worker 进程向 task 进程发送任务，task 进程处理完全部任务之后通过 onFinish 回调函数通知 worker 进程。例如，在后台操作向十万个用户群发通知邮件，操作完成后操作的状态显示为发送中，这时可以继续其他操作，等邮件群发完毕后，操作的状态自动改为已发送。
     * @param Server $server
     * @return void
     */
    public static function onWorkerStart(Server $server,int $workerId)
    {

    }


    /**
     * 1、此事件在 Worker 进程终止时发生。在此函数中可以回收 Worker 进程申请的各类资源。
     * 2、进程异常结束，如被强制 kill、致命错误、core dump 时无法执行 onWorkerStop 回调函数。
     * 3、请勿在 onWorkerStop 中调用任何异步或协程相关 API，触发 onWorkerStop 时底层已销毁了所有事件循环设施。
     * @param Server $server
     * @param int $workerId
     * @return void
     */
    public static function onWorkerStop(Server $server,int $workerId)
    {

    }

    /**
     * 1、仅在开启 reload_async 特性后有效。参见 如何正确的重启服务
     * @param Server $server
     * @param int $workerId
     * @return void
     */
    public static function onWorkerExit(Server $server, int $workerId)
    {

    }

    /**
     * 1、onConnect/onClose 这 2 个回调发生在 Worker 进程内，而不是主进程。
     * 2、UDP 协议下只有 onReceive 事件，没有 onConnect/onClose 事件
     * @param Server $server
     * @param int $fd 连续的文件描述符
     * @param int $reactorId 连接所在的 Reactor 线程 ID
     * @return void
     */
    public static function onConnect(Server $server, int $fd, int $reactorId)
    {

    }


    /**
     * 1、接收到数据时回调此函数，发生在 worker 进程中。
     * @param Server $server
     * @param int $fd
     * @param int $reactorId
     * @param string $data
     * @return void
     */
    public static function onReceive(Server $server, int $fd, int $reactorId, string $data)
    {

    }


    /**
     * TCP 客户端连接关闭后，在 Worker 进程中回调此函数。
     * 1、主动关闭
     *    当服务器主动关闭连接时，底层会设置此参数为 -1，可以通过判断 $reactorId < 0 来分辨关闭是由服务器端还是客户端发起的。
     *    只有在 PHP 代码中主动调用 close 方法被视为主动关闭
     * 2、心跳检测
     *    心跳检测是由心跳检测线程通知关闭的，关闭时 onClose 的 $reactorId 参数不为 -1
     * 3、onClose 回调函数如果发生了致命错误，会导致连接泄漏。通过 netstat 命令会看到大量 CLOSE_WAIT 状态的 TCP 连接
     * 4、无论由客户端发起 close 还是服务器端主动调用 $server->close() 关闭连接，都会触发此事件。因此只要连接关闭，就一定会回调此函数
     * 5、onClose 中依然可以调用 getClientInfo 方法获取到连接信息，在 onClose 回调函数执行完毕后才会调用 close 关闭 TCP 连接
     * 6、这里回调 onClose 时表示客户端连接已经关闭，所以无需执行 $server->close($fd)。代码中执行 $server->close($fd) 会抛出 PHP 错误警告
     * @param Server $server
     * @param int $fd
     * @param int $reactorId
     * @return void
     */
    public static function onClose(Server $server, int $fd, int $reactorId)
    {

    }


    /**
     * 1、在 task 进程内被调用。worker 进程可以使用 task 函数向 task_worker 进程投递新的任务。当前的 Task 进程在调用 onTask 回调函数时会将进程状态切换为忙碌，这时将不再接收新的 Task，当 onTask 函数返回时会将进程状态切换为空闲然后继续接收新的 Task。
     * 2、在 onTask 函数中 return 字符串，表示将此内容返回给 worker 进程。worker 进程中会触发 onFinish 函数，表示投递的 task 已完成，当然你也可以通过 Swoole\Server->finish() 来触发 onFinish 函数，而无需再 return
     * 3、return 的变量可以使任意非null的PHP变量
     * 4、onTask 函数执行时遇到致命错误退出，或者被外部进程强制 kill，当前的任务会被丢弃，但不会影响其他正在排队的 Task
     * @param Server $server
     * @param int $taskId 执行任务的task进程id
     * @param int $srcWorkerId
     * @param $data
     * @return void
     */
    public static function onTaskNoCoroutine(Server $server, int $taskId, int $srcWorkerId, $data)
    {

    }

    public static function onTaskEnableCoroutine(Server $server, Server\Task $task)
    {

    }

    /**
     * 1、此回调函数在 worker 进程被调用，当 worker 进程投递的任务在 task 进程中完成时， task 进程会通过 Swoole\Server->finish() 方法将任务处理的结果发送给 worker 进程
     * 2、task 进程的 onTask 事件中没有调用 finish 方法或者 return 结果，worker 进程不会触发 onFinish
     * 3、执行 onFinish 逻辑的 worker 进程与下发 task 任务的 worker 进程是同一个进程
     * @param Server $server
     * @param int $taskId
     * @param $data
     * @return void
     */
    public static function onFinish(Server $server, int $taskId, $data)
    {

    }

    /**
     * 1、当工作进程收到由 $server->sendMessage() 发送的 unixSocket 消息时会触发 onPipeMessage 事件。worker/task 进程都可能会触发 onPipeMessage 事件
     * @param Server $server
     * @param int $srcWorkerId
     * @param $message
     * @return void
     */
    public static function onPipeMessage(Server $server, int $srcWorkerId, $message)
    {

    }

    /**
     * 1、当 Worker/Task 进程发生异常后会在 Manager 进程内回调此函数。
     * 2、signal = 11：说明 Worker 进程发生了 segment fault 段错误，可能触发了底层的 BUG，请收集 core dump 信息和 valgrind 内存检测日志，向 Swoole 开发组反馈此问题
     * 3、exit_code = 255：说明 Worker 进程发生了 Fatal Error 致命错误，请检查 PHP 的错误日志，找到存在问题的 PHP 代码，进行解决
     * 4、signal = 9：说明 Worker 被系统强行 Kill，请检查是否有人为的 kill -9 操作，检查 dmesg 信息中是否存在 OOM（Out of memory）
     * 5、如果存在 OOM，分配了过大的内存。1. 检查 Server 的 setting 配置，是否 socket_buffer_size 等分配过大；2. 是否创建了非常大的 Swoole\Table 内存模块
     * @param Server $server
     * @param int $workerId
     * @param int $exitCode
     * @param int $signal
     * @return void
     */
    public static function onWorkerError(Server $server, int $workerId, int $exitCode, int $signal)
    {

    }

    /**
     * 1、当管理进程启动时触发此事件
     * 2、在这个回调函数中可以修改管理进程的名称。
     * 3、在 4.2.12 或更高版本中 manager 进程可以使用基于信号实现的同步模式定时器
     * 4、manager 进程中可以调用 sendMessage 接口向其他工作进程发送消息
     * 5、启动顺序：Task和worker进程已创建
     * 6、Master 进程状态不明，因为Manager与Master是并行的，不确定Master进程是否已就绪
     * 7、Base模式，在SWOOLE_BASE下，如果设置了worker_num,max_request,task_worker_num参数，底层将创建manager进程来管理工作进程，因此会触发onManagerStart和onManagerStop事件回调
     * @param Server $server
     * @return void
     */
    public static function onManagerStart(Server $server)
    {

    }


    /**
     * 1、当管理进程结束时触发
     * 2、onManagerStop 触发时，说明 Task 和 Worker 进程已结束运行，已被 Manager 进程回收。
     * @param Server $server
     * @return void
     */
    public static function onManagerStop(Server $server)
    {

    }


    /**
     * 1、Worker 进程 Reload 之前触发此事件，在 Manager 进程中回调
     * @param Server $server
     * @return void
     */
    public static function onBeforeReload(Server $server)
    {

    }

    /**
     * 1、Worker 进程 Reload 之后触发此事件，在 Manager 进程中回调
     * @param Server $server
     * @return void
     */
    public static function onAfterReload(Server $server)
    {

    }

}